﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Collections;

namespace RpgEditor
{
    public class ImageEx
    {
        public Image img;
        public int x;
        public int y;
        public int w;
        public int h;
        public String fn;
        public ImageEx(int x, int y, int w, int h)
        {
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
        }
    }

    public class ImageListEx
    {
        public Image img;
        public int tr;
        public int tc;

        public String fn;
        public ImageListEx(Image img,int tr, int tc, String fn)
        {
            this.img = img;
            this.tr = tr;
            this.tc = tc;
            this.fn = fn;
        }
    }

    public class Map
    {
        

        /** 场景id */
        int id = 0;

        /** 场景名称 */
        String name = "";

        /** 行块数量 */
        public int cols = 0;

        /** 列块数量 */
        public int rows = 0;

        /** 保存地图场景图块索引数据 */
        SByte[][] data = null;

        static public bundle jumpdata = null;
        public bool hasjumpdata = false;
        public String[] jdata;
        public string jumpfn = null;

        public ImageEx[] img = null;
        	static int TILED_WIDTH = 16;
        private String fn = null;
	static int TILED_HEIGHT = 16;

        mainForm form = null;

        public int currindex = -1;
        public ImageListEx[] imglist = null;


        public Map(mainForm f)
        {
            this.form = f;
            setFn(null);
            if (jumpdata == null)
                 jumpdata = new bundle();
        }

        public void setFn(String fn)
        {
            this.fn = fn;
            form.textBox6.Text = fn;
            if (fn != null)
            {
                jumpfn = Directory.GetParent(Directory.GetParent(fn).ToString()) + "/jumper.s";
                id = Int32.Parse(Path.GetFileNameWithoutExtension(fn));
            }
        }

        public String getFn()
        {
            return fn;
        }
        public void setRC(int r, int c)
        {
            rows = r;
            cols = c;
            data = new SByte[rows][];
            for (int y = 0; y < rows; y++)
            {
                data[y] = new SByte[cols];
                for (int k = 0; k < cols; k++)
                {
                    data[y][k] = (SByte)0;
                }
            }
        }
        public ImageEx[] CutImage(Image img, int width, int height)
        {
            
            int cols = img.Width / width;
            int rows = img.Height / height;
            ImageEx[] tmp = new ImageEx[cols * rows];
            int k = 0;
            int tmpx = 0, tmpy = 0;

            for (int i = 0; i < rows; i++)
            {
                tmpx = 0;
                for (int j = 0; j < cols; j++)
                {
                    ////tmp[k] = Image.createImage(img,
                    ////        tmpx,tmpy,width,height,
                    ////        javax.microedition.lcdui.game.Sprite.TRANS_NONE);
                    ////创建新图位图   
                    //Bitmap bitmap = new Bitmap(width, height);
                    ////bitmap.SetResolution(bitmap.HorizontalResolution, bitmap.VerticalResolution);
                    ////创建作图区域   
                    //Graphics graphic = Graphics.FromImage(bitmap);
                    ////截取原图相应区域写入作图区   
                    ////graphic.DrawImage(img, 0, 0, new Rectangle(tmpx,tmpy,width, height),GraphicsUnit.Pixel);
                    ////bitmap.MakeTransparent(Color.FromArgb(211, 211, 211));
                    
                    //graphic.DrawImage(img, new Rectangle(-tmpx, -tmpy, img.Width, img.Height));
                
                    //tmp[k] = Image.FromHbitmap(bitmap.GetHbitmap());
                    tmp[k] = new ImageEx(tmpx,tmpy,width,height);
                    tmp[k].img = img;
                    tmpx += width;
                    k++;
                }
                tmpy += height;
            }
            return tmp;
        }
        public void displayjump()
        {
            form.listBox14.Items.Clear();

            if (jdata != null)
            {

                int num = Int32.Parse(jdata[0]);
                for (int j = 0; j < num; j++)
                {
                    form.listBox14.Items.Add(j);
                }
                if (num > 0)
                {
                    form.listBox14.SelectedIndex = 0;

                    displayjump(0);
                }
            }
                    
        }
        public void displayjump(int i)
        {
            int num = Int32.Parse(jdata[0]);
            if (i >= num)
            {
                return;
            }
            int index = i * 6 + 1;
            form.textBox81.Text = jdata[index++] + "," + jdata[index++];
            form.textBox82.Text = jdata[index++] + "," + jdata[index++] + "," + jdata[index++] + "," + jdata[index++];
        }
        public void addjump()
        {
            if (jdata == null)
            {
                jdata = new string[6*1+1];
                jdata[0] = "1";
                String[] ts = form.textBox81.Text.Split(new Char[] { ',' });
                if (ts.Length < 2)
                {
                    return;
                }
                jdata[1] = ts[0];
                jdata[2] = ts[1];
                ts = form.textBox82.Text.Split(new Char[] { ',' });
                if (ts.Length < 4)
                {
                    return;
                }
                jdata[3] = ts[0];
                jdata[4] = ts[1];
                jdata[5] = ts[2];
                jdata[6] = ts[3];
                ArrayList list = jumpdata.data;
                bundledata b = new bundledata();
                b.data = jdata;
                b.key = "m" + id;
                list.Add(b);
            }
            else
            {
                int num = Int32.Parse(jdata[0]);
                num++;
                String[] tempdata = new String[num * 6 + 1];
                tempdata[0] = "" + num;
                int index = 1;
                for (; index < jdata.Length; index++)
                {
                    tempdata[index] = jdata[index];
                }
                String[] ts = form.textBox81.Text.Split(new Char[] { ',' });
                if (ts.Length < 2)
                {
                    return;
                }
                tempdata[index++] = ts[0];
                tempdata[index++] = ts[1];
                ts = form.textBox82.Text.Split(new Char[] { ',' });
                if (ts.Length < 4)
                {
                    return;
                }
                tempdata[index++] = ts[0];
                tempdata[index++] = ts[1];
                tempdata[index++] = ts[2];
                tempdata[index++] = ts[3];

                jdata = tempdata;

                ArrayList list = jumpdata.data;
                for (int i = 0; i < list.Count; i++)
                {
                    bundledata b = (bundledata)list[i];
                    if (b.key.Equals("m" + id))
                    {
                        b.data = jdata;
                        break;
                    }
                }
            }
        }
        public void upjump(int i)
        {
            int num = Int32.Parse(jdata[0]);
            if (i >= num)
            {
                return;
            }
            int index = i * 6 + 1;

            String[] ts = form.textBox81.Text.Split(new Char[] { ',' });
            if (ts.Length < 2)
            {
                return;
            }
            jdata[index++] = ts[0];
            jdata[index++] = ts[1];
            ts = form.textBox82.Text.Split(new Char[] { ',' });
            if (ts.Length < 4)
            {
                return;
            }
            jdata[index++] = ts[0];
            jdata[index++] = ts[1];
            jdata[index++] = ts[2];
            jdata[index++] = ts[3];
        }
        public void displayMap(int rr,int cc,int radio)
        {
            int sr = 0;
            int sc = 0;
            int er = rows;
            int ec = cols;

            if (rr != -1)
            {
                sr = rr - radio;
                if (sr < 0)
                    sr = 0;
                er = rr + radio;
                if (er > rows)
                {
                    er = rows;
                }
            }
            if (cc != -1)
            {
                sc = cc - radio;
                if (sc < 0)
                    sc = 0;
                ec = cc + radio;
                if (ec > cols)
                {
                    ec = cols;
                }
            }
            Graphics g = form.panel11.CreateGraphics();
            Rectangle rect1 = new Rectangle();
            rect1.X = 0;
            rect1.Y = 0;
            rect1.Height = form.panel11.Height;
            rect1.Width = form.panel11.Width;
            g.SetClip(rect1);
            if (rr == -1)
                g.Clear(form.BackColor);
            for (int i = sr; i < er; i++)
            {
                for (int j = sc; j < ec; j++)
                {
                    int index = data[i][j] & 0x7f;
                    if (index != 127)
                    {
                        Pen pen = new Pen(Color.Blue);
                        pen.Color = Color.Blue;
                        pen.Width = 1;
                        if (img != null && index < img.Length)
                        {
                            ImageEx ti = img[index];
                            Rectangle rect = new Rectangle();
                            rect.X = j * TILED_WIDTH;
                            rect.Y = (i+1) * TILED_HEIGHT - ti.h;
                            rect.Height = ti.h;
                            rect.Width = ti.w;
                            g.SetClip(rect);
                            g.DrawImage(ti.img, new Rectangle(j * TILED_WIDTH - ti.x, (i+1) * TILED_HEIGHT - ti.h - ti.y, ti.img.Width, ti.img.Height));
                            g.DrawRectangle(pen, j * TILED_WIDTH, (i+1) * TILED_HEIGHT - ti.h, ti.img.Width, ti.img.Height);
                        }
                        else
                        {
                            g.DrawRectangle(pen, j * TILED_WIDTH, i * TILED_HEIGHT - TILED_HEIGHT, TILED_WIDTH, TILED_HEIGHT);
                        }
                        
                    }
                }
            }
            for (int i = sr; i < er; i++)
            {

                for (int j = sc; j < ec; j++)
                {
                    int index = data[i][j] & 0x7f;
                    if (index != 127 && img != null)
                    {
                        ImageEx ti = img[index];
                        Rectangle rect = new Rectangle();
                        rect.X = j * TILED_WIDTH;
                        rect.Y = (i+1) * TILED_HEIGHT - ti.h;
                        rect.Height = ti.h;
                        rect.Width = ti.w;
                        g.SetClip(rect);

                        Pen pen = new Pen(Color.Blue);
                        if (data[i][j] < 0)
                        {
                            pen.Color = Color.Red;
                            pen.Width = 2;
                            g.DrawRectangle(pen, j * TILED_WIDTH, (i+1) * TILED_HEIGHT - TILED_HEIGHT, TILED_WIDTH, TILED_HEIGHT);
                        }
                    }
                }
            }
            // 显示原始图
            
            displayImgList();
            displayjump();
        }
        public bool adjust(int newrow,int newcol,int oldx,int oldy,int newx,int newy,int row,int col)
        {
            if (newrow <=0 || newcol <= 0)
            {
                return false;
            }
            if((oldx+col)>cols ||(oldy+row)> rows){
                return false;
            }
            sbyte[][] tempdata = new sbyte[newrow][];
            for (int j = 0; j < newrow; j++)
            {
                tempdata[j] = new sbyte[newcol];
            }
            for (int j = 0; j < row; j++)
            {
                
                for (int i = 0; i < col; i++)
                
                {
                    tempdata[newy + j][newx + i] = data[oldy + j][oldx + i];
                }
            }
            data = tempdata;
            rows = newrow;
            cols = newcol;
            return true;
        }
        public int getindex(int xpos, int ypos)
        {
            if (img != null)
            {
                int x = 0;
                int y = 0;
                int maxh = 0;
                for (int i = 0; i < img.Length; i++)
                {

                    ImageEx ti = img[i];
                    if (ti != null)
                    {
                        if ((x + ti.w) >= form.panel10.Width)
                        {
                            x = 0;
                            y = y + maxh + 5;
                            maxh = 0;
                        }
                        Rectangle rect = new Rectangle();

                        rect.X = x;
                        rect.Y = y;
                        rect.Height = ti.h;
                        rect.Width = ti.w;
                        if (rect.Contains(xpos, ypos))
                        {
                            return i;
                        }
                        x = x + ti.w + 5;
                        if (ti.h > maxh)
                        {
                            maxh = ti.h;
                        }
                    }
                }

            }
            return -1;
        }

        public void displayImgList()
        {
            
            Graphics g = form.panel10.CreateGraphics();
            Rectangle rect1 = new Rectangle();
            rect1.X = 0;
            rect1.Y = 0;
            rect1.Height = form.panel10.Height;
            rect1.Width = form.panel10.Width;
            g.SetClip(rect1);
            g.Clear(Color.Blue);
            if (img != null)
            {
                Rectangle temprect = new Rectangle(-1,-1,0,0);
                int x = 0;
                int y = 0;
                int maxh = 0;
                for (int i = 0; i < img.Length; i++)                
                {
                    
                    ImageEx ti = img[i];
                    if (ti != null)
                    {
                        if ((x + ti.w) >= form.panel10.Width)
                        {
                            x = 0;
                            y = y + maxh + 5;
                            maxh = 0;
                        }
                        Rectangle rect = new Rectangle();

                        rect.X = x;
                        rect.Y = y;
                        rect.Height = ti.h;
                        rect.Width = ti.w;
                        g.SetClip(rect);

                        g.DrawImage(ti.img, new Rectangle(x - ti.x, y - ti.y, ti.img.Width, ti.img.Height));
                        x = x + ti.w + 5;
                        if (ti.h > maxh)
                        {
                            maxh = ti.h;
                        }
                        if (i == currindex)
                        {
                            temprect = rect;
                        }
                    }
                }
                if (temprect.X != -1)
                {
                    g.SetClip(rect1);
                    Pen pen = new Pen(Color.Red);
                    g.DrawRectangle(pen, temprect);
                }
                
            }
        }

        public void save(String fn)
        {
   
            FileStream fs1 = new FileStream(fn, FileMode.Create, FileAccess.Write);
            BinaryWriter dis = new BinaryWriter(fs1, System.Text.Encoding.Default);
            MyIO.writeByte(dis,0);// layers
            MyIO.writeByte(dis, (SByte)(cols - 1));
            MyIO.writeByte(dis, (SByte)(rows - 1));

            MyIO.writeByte(dis, 0);   // tiledwidth
            MyIO.writeByte(dis, 0);   // tiledheight		

            // init tiledset
            // tiledset may be from more than one image
            //int imgnum = (Byte)(MyIO.readByte(dis));
            MyIO.writeByte(dis, (SByte)(imglist.Length));
            MyIO.writeByte(dis, (SByte)(img.Length));

            for (int i = 0; i < imglist.Length; i++)
            {
                MyIO.writeByte(dis, (SByte)(imglist[i].tc));
                MyIO.writeByte(dis, (SByte)(imglist[i].tr));
                String name = Path.GetFileNameWithoutExtension(imglist[i].fn);
               MyIO.writeString(dis,name);
                
            }

            // 读取动态图块数量
            // 动态图块好像没有用
            int dynamicNum = 0;
            MyIO.writeByte(dis, (SByte)dynamicNum);
            if (dynamicNum > 0)
            {
                //dynamicTiled = new Image[dynamicNum][];
                //dynamicTiledFrame = new byte[dynamicNum][3];
                for (int i = 0; i < dynamicNum; i++)
                {
                    MyIO.writeByte(dis, (SByte)dynamicNum);
                    MyIO.writeByte(dis, (SByte)dynamicNum);
                    //dynamicTiledFrame[i][0] = 0;
                    //dynamicTiledFrame[i][1] = length;
                    //dynamicTiledFrame[i][2] = index;
                    //dynamicTiled[i] = new Image[length];
                    //for(int j=0;j<length;j++){
                    //	dynamicTiled[i][j] = img[index+j];
                    //}
                }
            }

     
            for (int y = 0; y < rows; y++)
            {
                //dis.read(data[y]);
                for (int k = 0; k < data[y].Length; k++)
                {
                    MyIO.writeByte(dis, data[y][k]);
                }
            }

            dis.Close();
            dis = null;

            jumpdata.save(jumpfn);
        }

        public void loadLocalResource(String fn)
        {
            id = Int32.Parse(Path.GetFileNameWithoutExtension(fn));
            FileStream fs1 = new FileStream(fn, FileMode.Open, FileAccess.Read);
            BinaryReader dis = new BinaryReader(fs1, System.Text.Encoding.Default);
            MyIO.readByte(dis);  // layers

            // 为什么要+1？
            cols = (Byte)(MyIO.readByte(dis)) + 1;
            rows = (Byte)(MyIO.readByte(dis)) + 1;

            MyIO.readByte(dis);   // tiledwidth
            MyIO.readByte(dis);   // tiledheight		

            // init tiledset
            // tiledset may be from more than one image
            int imgnum = (Byte)(MyIO.readByte(dis));
            int tilednum = (Byte)(MyIO.readByte(dis));
            int pos = 0;
            // 多出一个来放打开时的宝箱图片
            img = new ImageEx[tilednum];
            imglist = new ImageListEx[imgnum];
   
            for (int i = 0; i < imgnum; i++)
            {
                int tc = (Byte)(MyIO.readByte(dis));
                int tr = (Byte)(MyIO.readByte(dis));
                String name = MyIO.readString(dis);
                //#if ADAM
                //#if SAMSUNG || LG_KG800
                //# Image tmp[] = GameCanvas.CutImage(GameCanvas.LoadImage("/map/"+name+".png"),
                //# tc,tr,true);
                //#else
                String dir = Path.GetDirectoryName(fn);
                String pngfn = (dir + "/" + name + ".png");
                Image img1 = Image.FromFile(pngfn);
                imglist[i] = new ImageListEx(img1,tr,tc,pngfn);

                ImageEx[] tmp = CutImage(img1, tc, tr);
                //#endif
                //#else
                //#if SAMSUNG
                //# Image tmp[] = GameCanvas.CutImage(
                //# Resource.getImage(name+".png"),
                //# tc,tr,true);
                //#else
                //# Image tmp[] = GameCanvas.CutImage(
                //# Resource.getImage(name+".png"),
                //# tc,tr);
                //#endif
                //#endif
                //System.arraycopy(tmp,0,img,pos,tmp.length);
                for (int k = 0; k < tmp.Length; k++)
                {
                    tmp[k].fn = pngfn;
                    img[pos] = tmp[k];
                    //Console.Out.WriteLine(img[pos].Width+","+img[pos].Height);
                    //img[pos].img.Save("d:/temp/" + pos + ".png");
                    pos++;
                }
                //pos+=tmp.length;
            }

            // 读取动态图块数量
            // 动态图块好像没有用
            int dynamicNum = MyIO.readByte(dis);
            if (dynamicNum > 0)
            {
                //dynamicTiled = new Image[dynamicNum][];
                //dynamicTiledFrame = new byte[dynamicNum][3];
                for (int i = 0; i < dynamicNum; i++)
                {
                    SByte index = MyIO.readByte(dis);
                    SByte length = MyIO.readByte(dis);
                    //dynamicTiledFrame[i][0] = 0;
                    //dynamicTiledFrame[i][1] = length;
                    //dynamicTiledFrame[i][2] = index;
                    //dynamicTiled[i] = new Image[length];
                    //for(int j=0;j<length;j++){
                    //	dynamicTiled[i][j] = img[index+j];
                    //}
                }
            }

            data = new SByte[rows][];
            for (int y = 0; y < rows; y++)
            {
                data[y] = new SByte[cols];
                //dis.read(data[y]);
                Byte[] tt = dis.ReadBytes(cols);
                for (int k = 0; k < tt.Length; k++)
                {
                    data[y][k] = (SByte)(tt[k]);
                }
            }

            dis.Close();
            dis = null;

            jumpdata.load(jumpfn);
            hasjumpdata = true;
            jdata = null;
            ArrayList list = jumpdata.data;
            for (int i = 0; i < list.Count; i++)
            {
                bundledata b = (bundledata)list[i];
                if (b.key.Equals("m" + id))
                {
                    jdata = b.data;                    
                    break;
                }
            }
        }

        public bool addimg(String fn,int tr,int tc)
        {
            String png = Path.GetDirectoryName(getFn()) + "/" + fn + ".png";
            if (!File.Exists(png))
            {
                return false;
            }
            Image ti = Image.FromFile(png);



            ImageEx[] tmpex = CutImage(ti, tc, tr);
            if (tmpex == null || tmpex.Length <= 0)
                return false;
            if (img != null)
            {
                ImageEx[] newimg = new ImageEx[img.Length + tmpex.Length];
                for (int i = 0; i < img.Length; i++)
                {
                    newimg[i] = img[i];
                }
                int pos = img.Length;
                for (int k = 0; k < tmpex.Length; k++)
                {
                    tmpex[k].fn = png;
                    newimg[pos] = tmpex[k];
                    pos++;
                }
                img = newimg;
            }
            else
            {
                img = tmpex;
            }
            ImageListEx il = new ImageListEx(ti, tr, tc, png);
            if (imglist == null)
            {
                imglist = new ImageListEx[1];
                imglist[0] = il;
            }
            else
            {
                ImageListEx[] tmp = new ImageListEx[imglist.Length + 1];
                for (int i = 0; i < imglist.Length; i++)
                {
                    tmp[i] = imglist[i];
                    if (imglist[i].fn.Equals(png))
                    {
                        return false;
                    }
                }


                tmp[imglist.Length] = il;
                imglist = tmp;
            }
            return true;
        }

        public bool setImg(int x, int y,bool flag)
        {
            Point p=new Point(-1,-1);
            if (flag)
            {
                p = getindex1(x, y);
            }
            else
            {
                p.X = x;
                p.Y = y;            }
            if (p.X != -1)
            {
                SByte i = (SByte)currindex;
                data[p.X][p.Y] = (SByte)(data[p.X][p.Y] & 0x80);
                data[p.X][p.Y] = (SByte)(data[p.X][p.Y] | i);
            }
            return true;
        }

        
        public Point getindex1(int x, int y)
        {
            Point p = new Point(-1, -1);
            for (int i = 0; i < rows; i++)
            {

                for (int j = 0; j < cols; j++)
                {


                    Rectangle rect = new Rectangle();
                    rect.X = j * TILED_WIDTH;
                    rect.Y = (i+1) * TILED_HEIGHT - TILED_HEIGHT;
                    rect.Height = TILED_HEIGHT;
                    rect.Width = TILED_WIDTH;

                    if (rect.Contains(x, y))
                    {
                        p.X = i;
                        p.Y = j;
             
                        return p;
                    }

                }
            }
            return p;
        }
        public bool setblock(int x, int y)
        {
           Point p = getindex1(x,y);
            if (p.X != -1)
            {
                if (data[p.X][p.Y] < 0)
                            {
                                data[p.X][p.Y] = (SByte)(data[p.X][p.Y] & 0x7f);//01111111
                            }
                            else
                            {
                                data[p.X][p.Y] = (SByte)(data[p.X][p.Y] | 0x80);
                            }
                            return true;                    

                
            }
            return false;
        }
    }
}
